﻿<!doctype html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>组件化</title>
    <link href="/resources/Doc/css/style.css" rel="stylesheet" />
    <link href="/resources/Doc/lib/responsive.css" rel="stylesheet" />
    <!--[if lt IE 9]><script src="/resources/Doc/lib/H5shiv.js"></script><![endif]-->
</head>

<body class="hasNav">
    <header class="wrap">
        <h1>组件化框架使用文档</h1>
    </header>
    <nav class="wrap nav" id="nav"></nav>
    <section class="wrap" id="overall">
        <h2>概述</h2>
        <h3 id="overall-about">关于框架</h3>
        <p>底层基于<a href="http://192.168.50.33/" target="_blank">模块化框架</a>，同样的模块化开发方式，同样的图标库、栅格系统，使用<a href="http://oak.baidu.com/docs/pure" target="_blank">fis_pure</a>作为组件化解决方案，得益于fis强大的编译功能，还实现了样式less化、css语法糖、全局样式配置、前端自动性能优化等功能。</p>
        <h3 id="overall-files">目录结构</h3>
        <pre>
      <code class="javascript">
../                                 //网站根目录
  source/                               //前端工程目录（不提交svn）
    |--less/ 
    |   |--base-mobile.less 
    |   |--base-responsive.less
    |   |--grid.less
    |   |--reset.less 
    |   |--set.less  
    |   `--tools.less 
    |--modules/                             
    |--widget/                              
    |   |-- news/       
    |   |-- pro/
    |   |-- history/
    |   `-- ...
    |--web/                                           //模板项目
    |   |-- app/                            
    |   |-- css/                            
    |   |     |-- global.less
    |   |     |-- Mobile.mixin.less
    |   |     |-- Pad.mixin.less
    |   |     `-- style.mixin.less
    |   |-- img/
    |   |-- lib/
    |   `-- index.htm
    |--test/ 
    `--fis-conf.js 
  resources/                            //前端部署目录（提交svn）
    |--modules/
    |--pkg/                                 
    |--web/
    |--widget/
    `--map.json                             
      </code>
   </pre>
        <h3 id="overall-env">开发环境</h3>
        <h4>安装nodejs</h4>
        <ol>
            <li>nodejs</li>
            <li>java（可选）</li>
            <li>php（可选）</li>
        </ol>
        <h4>安装pure</h4>
        <pre>
     <code>
       npm install fis-pure -g
     </code>
   </pre>
        <h3 id="overall-start">开始使用</h3>
        <p>打开cmd或者nodejs命令行工具，定位在前端工程目录（如 E:\Git\_fis_pure\source），输入：</p>
        <pre>
    <code>
      pure release
    </code>
   </pre>
        <p>编译系统应该开始编译项目工程目录了，默认编译后的发布目录是系统站点（C:\Users\Administrator\AppData\Local\.fis-pure-tmp\www），启动内置调试服务器（或自己配置IIS服务器）即可预览，输入：</p>
        <pre>
     <code>
       pure server start
     </code>
   </pre>
        <p>启动内置调试服务器需要java和php，否则需要输入
            <em>pure server start --type-node</em> 启动nodejs版服务器。</p>
        <h4>与模块化框架的几点区别</h4>
        <ol>
        <li>模块加载器换成<a href="https://github.com/fex-team/mod" target="_blank">mod.js</a>，模块不需要加adm模块包装，编译后会自动添加包装和id，id规则后面会介绍到；</li>
        <li>开发中使用less，less特性见<a href="http://www.lesscss.net/" target="_blank">less官网</a>；</li>
        </ol>

    </section>
    <section class="wrap" id="function">
        <h2>详细介绍</h2>
        <h3 id="function-api">命令及参数</h3>
        <h4>pure server</h4>
        <ol>
            <li>pure server start，启动调试服务器</li>
            <li>pure server open，打开服务器所在目录</li>
        </ol>
        <h4>pure release</h4>
        <ol>
            <li>-w ，监听文件变化触发自动编译</li>
            <li>-d ，配置部署目录，默认发布在系统站点目录，参数后空格可以跟一个具体目录，或者跟一个配置名称，框架内置本地发布配置名称为
                <em>local</em>，使用中应该写成
                <em>pure release -d local</em>
            </li>
            <li>-m ，为静态文件添加md5戳，用于静态文件可以及时更新CDN缓存，平时不需要</li>
            <li>-p ，打包合并静态文件并自动优化</li>
            <li>-o ，压缩静态文件</li>
        </ol>
        <p>日常开发常用的就是<b>-w -p -d</b>，可以简写为<b>pure release -pwd local</b>
        </p>
        <h3 id="function-road">编译规则</h3>
        <h4>编译原理</h4>
        <p>工程目录的结构基本与模块化框架保持一致，通过编写编译规则，编译系统可以将工程目录发布至任意部署目录，过程分编译和发布两个步骤，编译开始时，有的文件不需要参与编译，比如psd文件，编译时会自动跳过，参与编译的文件应该都能被编译规则匹配，根据规则采取下一步动作，比如嵌入依赖、编译格式、文件合并等等，然后进入发布阶段，在这个阶段有的文件不需要参与发布，比如/source/less/中的文件，它们只作为发布样式的"生产资料"，编译过程中被混入到其他文件中，被混入以后这些"生产资料"就没有价值了，最终生成的样式只有一个/source/web/css/global.less【以下简称global.less】，其他碎片样式都不会发布出来。</p>
        <h4>less/</h4>
        <p>/source/less/中的文件负责配置全局样式，只编译不发布，它们会混入到global.less中，其中，base-mobile.less 和base-responsive.less 分别是移动项目配置和响应式项目配置，项目开始前需要在global.less中引用对应的配置文件：</p>
        <pre>
          <code>
// Base
@import "../../less/base-mobile.less";
          </code>
        </pre>
        <p>/source/less/里剩下的文件grid.less、reset.less 、set.less 、tools.less 分别是栅格系统、样式重置、全局配置、工具样式库，把他们单独剥离出来方便有针对性的调整。</p>
        <h4>modules/</h4>
        <p>/source/modules/中的模块全部来自模块化框架，根据新框架规则改写，用法没有区别，id规则比之前更方便，除了modules/中的模块文件可以直接require('文件名')以外，同名文件夹下的模块如modules/album/album.js，也可以直接require('album')。</p>
        <p>该文件夹中的文件全部参与编译和发布，打包后会按需合并到发布后的pkg/文件夹。</p>
        <h4>widget/</h4>
        <p>/sources/widget/存放所有的组件。组件中的htm文件会被编译到模板页面中，不参与发布；less文件会编译成css文件原目录发布，js文件原目录发布。</p>
        <h4>web/</h4>
        <p>/source/web/整体原目录发布。</p>
        <p>app/文件夹id规则为"项目名/js名"，比如web/app/index.js，项目名为web，js名为index，所以id为web/index，其他以此类推web/about、web/job...</p>
        <p>css/文件夹中只有global.less最后发布，Mobile.mixin.less、Pad.mixin.less、style.mixin.less编译中都会混入到global.less，它们分别是手机样式、pad样式、pc样式（也是移动项目的默认样式）。</p>
        <p>img/是图片文件夹，按原目录发布。</p>
        <p>lib/是非模块化文件，不编译，按原目录发布。</p>
        <p>index.htm(模板页面)编译过程中会嵌入依赖css、js，并将引用的组件HTML编译进来，应用打包（-p）会自动优化，合并css在头部，合并js在底部，最后按原目录发布。</p>
        <h4>fis-config.js</h4>
        <p>编译配置文件，编译中可以监听到配置文件变化，但是在下次运行pure release 命令之前不会生效。</p>
        <h4>部署目录</h4>
        <p>最终发布出来的部署目录是与工程目录同级的resources/文件夹，内部包括modules/、pkg/、web/、widget/、map.json，打包后的js和css文件在pkg/中并自动在模板中引用，map.json是编译系统生成的静态资源表，包含项目中每一个资源文件的地址和依赖信息，用于后端做按需加载或资源使用量统计等。</p>
        <h3 id="function-tools">css类</h3>
        <p>面向对象的css组织方式鼓励建立重用类库，像模块化框架中的style.css包含的common部分，重用类分两种：</p>
        <p>一种是工具类，可以直接完成一项特定任务，比如mt20等于margin-top:20px，工具类的意义是减少css代码量，缺点是功能往往很弱、增加HTML代码量、降低css维护性，改善维护性的方法是将样式值抽象，例如"mt-normal"，这种就可以方便的在样式表中修改样式值而不需要动HTML文件，但在面向展现的项目中需要更强的需求分析能力，一旦需求变化超出预期就会因为复杂的重用关系无法直接修改工具类，变的更难维护；<p>
        <p>另一种是基类，只完成复杂任务的一部分，其余部分交给其他样式补充，比如.arr等于display: inline-block; width: 0; height: 0; overflow: hidden; ，是css画图必须的代码，实际项目中可能会出现这样的代码：&lt;i class=&quot;arr myFigure&quot;&gt;&lt;/i&gt;，然后由.myFigure实现具体形状、颜色、大小等部分，基类试图实现复杂任务的解耦，理想状态是将UI实现和皮肤分离，做到实现公用皮肤定制，但是受限于css语言能力无法实现。</p>
        <p>利用less的语言特性，可以实现更强大的css类，/source/less/tools.less中除了普通公用样式外，还包括以下用于混合的类：</p>
        <table class="table table-bordered">
          <tr>
            <td>.button</td>
            <td>
            <p>按钮，定义按钮的基础样式。</p>
            <pre>
              <code>
._btn{
  .button;
}
              </code>
            </pre>
            <p>以上编译后会生成：</p>
            <pre>
              <code>
._btn{
  display: inline-block;
  padding: 0 2em;
  border-radius: 3px;
  line-height: 2em;
  color: #ffffff;
  background: #cccccc;
  cursor: pointer;
  overflow: hidden;
}
              </code>
            </pre>
            </td>
          </tr>
          <tr>
            <td>.button-b</td>
            <td>
              <p>带背景定义的按钮，同时会生成:hover状态。</p>
              <pre>
                <code>
._btn{
  .button-b(green);
}
                </code>
              </pre>
              <p>以上编译后会生成：</p>
            <pre>
              <code>
._btn{
  display: inline-block;
  padding: 0 2em;
  border-radius: 3px;
  line-height: 2em;
  color: #ffffff;
  background: #cccccc;
  cursor: pointer;
  overflow: hidden;
  background: #008000;
}
._btn:hover {
  background: #006100;
  color: #dcffdc;
}
              </code>
            </pre>
            </td>
          </tr>
          <tr>
            <td>.img-prop</td>
            <td>
              <p>自定义比例元素，接受两个数字作参数，分别表示宽和高的比例值，例如16:9的图片写为：</p>
              <pre>
                <code>
&lt;div class=&quot;img&quot;&gt;
  &lt;img src=&quot;http://usr.im/160x90&quot;&gt;
&lt;/div&gt;
                </code>
                <code>
.img{
  .img-prop(16,9);
}
                </code>
              </pre>
              <p>以上编译后会生成：</p>
              <pre>
                <code>
.img {
  display: block;
  position: relative;
  width: 100%;
  height: 0;
  overflow: hidden;
  padding-bottom: 56.25%;
}
.img img,
.img ._inner {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
}
                </code>
              </pre>
            </td>
          </tr>
          <tr>
            <td>...</td>
            <td>
              <p>...</p>
            </td>
          </tr>
        </table>
        
    </section>
    <section class="wrap" id="best">
        <h2>最佳实践</h2>
        <ol>
            <li>带完整组件库监听编译每次需要1-2秒的时间，不带组件库基本能立刻完成编译，开发中可以先不带组件库，过程中用到哪个组件就复制哪个组件进项目，提高编译速度；</li>
            <li>...</li>
        </ol>
    </section>

    <footer class="wrap oh tc">
        <div class="row ">
            <a href="#" title="返回顶部" class="dib foot_logo gotop">
                <figure></figure>
            </a>
            <p class="dib">© 2014 - 3014 zangtao@jerei.com</p>
        </div>
    </footer>
</body>
<script src="/resources/modules/seajs/sea.js" id="seajs-node"></script>
<script src="/resources/Doc/seajs.config.js"></script>
<script>
seajs.use('/resources/Doc/resets/doc')
</script>

</html>
